/* entity */
import Field from '@model/entity/Field'
/* model */
import { SelectColumnTree, SelectColumnTreeNode } from '@src/component/business/BizSelectColumn/BizSelectColumnModel'
import { fieldArrayToObject } from '@src/util/array'
/* util */
import { isArray, isEmpty, isObject } from '@src/util/type'

/**
 * @description 转换显示名称属性为名称属性方法
 * @param {Field} field 字段数据
 * @return {Field} 转换后的字段数据
 */
export function convertDisplayNameToName(field: Field): Field {
  field.name = field.displayName || field.label
  return field
}

/**
 * @description 转换列数据 为了保存的时候使用的
 * @param {Field} field 字段数据
 * @return {Field}
 */
export function convertColumnWithSave(field: Field): Field {
  let column = {
    ...field,
    show: field.show,
  }
  return column
}

export function upwardToggleChecked(tree: SelectColumnTree) {
  let rootTreeNode: SelectColumnTreeNode
  let attributeColumns: Record<string, SelectColumnTreeNode>
  let columns: Field[] = []
  
  for (let rootTreeNodeKey in tree) {
    rootTreeNode = tree[rootTreeNodeKey]
    
    if (isArray(rootTreeNode.columns)) {
      computedColumnsParentChecked(rootTreeNode.columns as Field[], rootTreeNode)
      continue
    }
    
    if (!isObject(rootTreeNode.columns)) return
    
    // 自定义字段的列数据
    attributeColumns = rootTreeNode.columns as Record<string, SelectColumnTreeNode>
    for (let columnKey in attributeColumns) {
      columns = attributeColumns[columnKey].columns as Field[]
      computedColumnsParentChecked(columns, attributeColumns[columnKey])
    }
    
  }
}

function computedColumnsParentChecked(columns: Field[], selectTreeNode: SelectColumnTreeNode) {
  selectTreeNode.checked = columns.every(column => column.show)
}

export function columnTreeToObject(columnTree: SelectColumnTree): Record<string, Field> {
  console.log(columnTree, 'columnTreecolumnTree')
  const SystemFields = columnTree?.system?.columns as Field[] || []
  const CommonFields = columnTree?.common?.columns as Field[] || []
  const ProductSystemFields = columnTree?.productSystem?.columns as Field[] || []
  const CatalogSystemFields = columnTree?.catalogSystem?.columns as Field[] || []
  const CustomerSystemFields = columnTree?.customerSystem?.columns as Field[] || []
  const CustomerContactSystemFields = columnTree?.customerContactSystem?.columns as Field[] || []
  const imSystemFields = columnTree?.imSystem?.columns as Field[] || []
  const serviceProviderSystemFields = columnTree?.serviceProvider?.columns as Field[] || []
  const paymentBillOnlineSystem = columnTree?.paymentBillOnlineSystem?.columns as Field[] || []
  const ContractSystem =  columnTree?.contractSystem?.columns as Field[] || []
  const ProductRegisterSystem = columnTree?.productRegisterSystem?.columns as Field[] || []
  const providerSystem = columnTree?.providerSystem?.columns as Field[] || []
  const engineerSystem = columnTree?.engineerSystem?.columns as Field[] || []
  const ProjectSystem =  columnTree?.projectSystem?.columns as Field[] || []

  const ProductAttributeFields = columnTree?.productAttribute?.columns as Field[] || []
  const CatalogAttributeFields = columnTree?.catalogAttribute?.columns as Field[] || []
  const CustomerAttributeFields = columnTree?.customerAttribute?.columns as Field[] || []
  const CustomerContactAttributeFields = columnTree?.customerContactAttribute?.columns as Field[] || []
  const AttributeFieldsTreeNodeFields = columnTree?.attribute?.columns as Record<string, SelectColumnTreeNode> || {}
  const CustomerSatisfactionFields = columnTree?.customerSatisfaction?.columns as Record<string, SelectColumnTreeNode> || {}
  const imAttributeFields = columnTree?.imAttribute?.columns as Field[] || []
  const ContractAttribute = columnTree?.contractAttribute?.columns as Field[] || []
  const providerAttribute = columnTree?.providerAttribute?.columns as Field[] || []
  const engineerAttribute = columnTree?.engineerAttribute?.columns as Field[] || []
  const ProductRegisterAttribute = columnTree?.productRegisterAttribute?.columns as Field[] || []
  const ProjectAttribute =  columnTree?.projectAttribute?.columns as Field[] || []
  
  return {
    ...fieldArrayToObject(SystemFields),
    ...fieldArrayToObject(CommonFields),
    ...fieldArrayToObject(ProductSystemFields),
    ...fieldArrayToObject(CatalogSystemFields),
    ...fieldArrayToObject(CustomerSystemFields),
    ...fieldArrayToObject(imSystemFields),
    ...fieldArrayToObject(CustomerContactSystemFields),
    ...fieldArrayToObject(ProductAttributeFields),
    ...fieldArrayToObject(CatalogAttributeFields),
    ...fieldArrayToObject(CustomerAttributeFields),
    ...fieldArrayToObject(CustomerContactAttributeFields),
    ...columnTreeAttributeColumnsToObject(AttributeFieldsTreeNodeFields),
    ...columnTreeAttributeColumnsToObject(CustomerSatisfactionFields),
    ...fieldArrayToObject(imAttributeFields),
    ...fieldArrayToObject(serviceProviderSystemFields),
    ...fieldArrayToObject(paymentBillOnlineSystem),
    ...fieldArrayToObject(ContractSystem),
    ...fieldArrayToObject(ContractAttribute),
    ...fieldArrayToObject(ProductRegisterSystem),
    ...fieldArrayToObject(ProductRegisterAttribute),
    ...fieldArrayToObject(providerSystem),
    ...fieldArrayToObject(providerAttribute),
    ...fieldArrayToObject(engineerSystem),
    ...fieldArrayToObject(engineerAttribute),
    ...fieldArrayToObject(ProjectSystem),
    ...fieldArrayToObject(ProjectAttribute),
  }
}

function columnTreeAttributeColumnsToObject(attributeColumnsObject: Record<string, SelectColumnTreeNode>): Record<string, Field> {
  if (!attributeColumnsObject) return {}
  
  let attributeColumns: Field[] = []
  let columnTreeAttributeColumnsObject: Record<string, Field> = {}
  
  for (let key in attributeColumnsObject) {
    attributeColumns = attributeColumnsObject[key].columns as Field[]
    columnTreeAttributeColumnsObject = {
      ...columnTreeAttributeColumnsObject,
      ...fieldArrayToObject(attributeColumns)
    }
  }
  
  return columnTreeAttributeColumnsObject
}

/**
 * @description 通过关键词过滤树数据
 * @param {SelectColumnTree} tree 原始的树
 * @param {String} keyword 关键词
 * @return {SelectColumnTree} 过滤后的树
 */
export function filterTreeWithKeywordHandler(tree: SelectColumnTree, keyword: string): SelectColumnTree {
  let filterTree: SelectColumnTree = {}
  let node: SelectColumnTreeNode
  
  for (let key in tree) {
    node = tree[key]
    
    filterTree[key] = {
      ...node,
      columns: getFilterTreeColumnsWithKeywordHandler<Field[]>(node, keyword, [])
    }
    
  }
  
  return filterTree
}

function getFilterTreeColumnsWithKeywordHandler<T>(
  orginTreeNode: SelectColumnTreeNode, 
  keyword: string, 
  defaultValue: T
): Field[] | Record<string, SelectColumnTreeNode> | T {
  // 数组类型的列
  if (isArray(orginTreeNode.columns)) {
    let columns: Field[] = orginTreeNode.columns as Field[]
    return columns.filter(field => filterColumnWithKeywordCallback(field, keyword))
  }
  
  if (isObject(orginTreeNode.columns)) {
    let orginTreeNodeColumns: Record<string, SelectColumnTreeNode> = orginTreeNode.columns as Record<string, SelectColumnTreeNode>
    let treeNodeColumns: Record<string, SelectColumnTreeNode> = {}
    let columns: Field[] = []
    let filterWithKeywordCallbackColumns: Field[] = []
    
    for(let key in orginTreeNodeColumns) {
      columns = orginTreeNodeColumns[key].columns as Field[]
      filterWithKeywordCallbackColumns = columns.filter(field => filterColumnWithKeywordCallback(field, keyword))
      
      if (!isEmpty(filterWithKeywordCallbackColumns)) {
        treeNodeColumns[key] = {
          ...orginTreeNodeColumns[key],
          columns: columns.filter(field => filterColumnWithKeywordCallback(field, keyword))
        }
      }
      
    }
    
    return treeNodeColumns
  }
  
  return defaultValue
}

function filterColumnWithKeywordCallback(field: Field, keyword: string): boolean {
  if (!field?.displayName) return false
  
  return field.displayName.indexOf(keyword) > -1
}
